Author: Jorge Maldonado Ventura
Category: Python
Date: 2017-05-07 18:26
Image: <img src="/wp-content/uploads/2017/05/programa-internacionalizado.png" alt="Programa internacionalizado">
Lang: es
Modified: 2018-03-19 13:12
Slug: internacionalización-de-programas-python
Tags: edición de texto, editores de texto, GNU/Linux, internacionalización, localización, Poedit, programación, pygettext, Python, Python 3, regionalización, traducción
Title: Internacionalización de programas Python

La
[internacionalización](https://es.wikipedia.org/wiki/Internacionalizaci%C3%B3n_y_localizaci%C3%B3n)
de programas permite que estos puedan ser entendidos por personas que
hablan idiomas diferentes.

En este artículo enseño cómo internacionalizar un programa escrito en
Python 3. Para este propósito se suele utilizar el módulo
[gettext](https://docs.python.org/3/library/gettext.html), que esta
incluido en Python.

<!-- more -->

Antes de nada, debemos tener un programa para poder traducirlo. Vamos a
traducir el siguiente programa llamado `saluda.py`:

    :::python3
    #!/usr/bin/env python3

    nombre = input('¿Cómo te llamas? ')
    print('Hola, {}.'.format(nombre))

El programa es muy sencillo. Pregunta al usuario su nombre y le saluda
por su nombre o, mejor dicho, le vuelve a repetir lo que el usuario ha
escrito.

Para internacionalizar el programa anterior vamos a importar el módulo
gettext y a ejecutar la función `install` de gettext. Después, debemos
rodear el texto que queramos traducir con `_()`, es decir, si queremos
traducir `'texto'` escribiremos
`_('texto')`.

    :::python3
    #!/usr/bin/env python3

    import gettext

    gettext.install('saluda', 'locale')

    nombre = input(_('¿Cómo te llamas? '))
    print(_('Hola, {}.').format(nombre))

Ahora creamos el directorio `locale`, donde guardaremos las traducciones:

```
mkdir locale
```

Después debemos ejecutar pygettext, que viene instalado con Python.
Quizás debéis ejecutar pygettext3 para indicar que queréis trabajar con
Python 3:

```
pygettext -d saluda -p locale saluda.py
```

Yo lo hice así desde la terminal:

<a href="/wp-content/uploads/2017/05/usando-pygettext.png">
<img src="/wp-content/uploads/2017/05/usando-pygettext.png" alt="Ejecutando pygettext">
</a>

Ahora tenemos el archivo `saluda.pot` en el directorio `locale`. Para
trabajar con archivos de traducción es recomendable usar un editor
preparado para dicha tarea, porque hacerlo a mano es muy tedioso.
Podemos usar el editor Poedit o cualquier otro editor diseñado para
traducir.

Si vamos a utilizar Poedit, seleccionamos **Archivo>Nueva desde archivo
POT/PO** y seleccionamos el archivo `saluda.pot`. A continuación,
debemos seleccionar el idioma al que queremos traducir, yo voy a elegir
el alemán.

<a href="/wp-content/uploads/2017/05/Poedit-seleccionando-idioma.png">
<img src="/wp-content/uploads/2017/05/Poedit-seleccionando-idioma.png" alt="Seleccionando idioma para traducción con Poedit" width="1018" height="520" srcset="/wp-content/uploads/2017/05/Poedit-seleccionando-idioma.png 1018w, /wp-content/uploads/2017/05/Poedit-seleccionando-idioma-509x260.png 509w" sizes="(max-width: 1018px) 100vw, 1018px">
</a>

Cuando terminemos la traducción, debemos guardarla:

<a href="/wp-content/uploads/2017/05/Poedit-guardando-traducción.png">
<img src="/wp-content/uploads/2017/05/Poedit-guardando-traducción.png" alt="Guardando traducción con Poedit" width="1439" height="932" srcset="/wp-content/uploads/2017/05/Poedit-guardando-traducción.png 1439w, /wp-content/uploads/2017/05/Poedit-guardando-traducción-719x466.png 719w" sizes="(max-width: 1439px) 100vw, 1439px">
</a>

Se generarán dos archivos: `de.po` y
`de.mo`. El archivo `de.po` es legible por los humanos y el archivo
`de.mo` es legible por la máquina. El archivo `de.mo` debe guardarse
según la siguiente estructura de ficheros:
`locale/de/LC_MESSAGES/de.mo`. Para que no tengamos que acordarnos de la
anterior estructura cada vez que creemos o actualicemos una traducción,
podemos ubicar el siguiente programa en el directorio `locale` y
ejecutarlo cada vez que actualicemos un archivo `.po`:

    :::python3

    #!/usr/bin/env python3
    # Copyright (C) 2016 Julie Marchant <onpon4@riseup.net>
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation, either version 3 of the License, or
    # (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program.  If not, see <http://www.gnu.org/licenses/>.

    import os
    import subprocess

    if __name__ == "__main__":
        for fname in os.listdir():
            root, ext = os.path.splitext(fname)
            if ext == ".po":
                print("Generando {}...".format(fname))
                d, root = os.path.split(root)
                os.makedirs(os.path.join(d, root, "LC_MESSAGES"), exist_ok=True)
                oname = os.path.join(d, root, "LC_MESSAGES", "saluda.mo")
                subprocess.call(["msgfmt", "-o", oname, fname])

        print("Terminado.")


Tras ejecutar el anterior programa, ya tendremos los archivos de
traducción donde corresponden. Al ejecutar `saluda.py` se utilizará el
idioma por defecto del sistema operativo que lo ejecute. Es decir, si
estamos utilizando el alemán como el idioma predeterminado del sistema
operativo, el programa se ejecutará en alemán. Podemos comprobar si
funciona para este idioma cambiando la variable de entorno LANGUAGE en
el caso de que estemos trabajando con GNU/Linux. Se puede probar así:

<a href="/wp-content/uploads/2017/05/programa-internacionalizado.png">
<img src="/wp-content/uploads/2017/05/programa-internacionalizado.png" alt="Programa internacionalizado">
</a>
